package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.constant.BspsServiceNameConstant;
import cc.rengu.igas.bsps.common.constant.BspsTreeNodeConstant;
import cc.rengu.igas.bsps.common.dao.BspSequenceMapper;
import cc.rengu.igas.bsps.common.dao.BspsMchntBaseInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsMchntBindInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsQrCodeInfoMapper;
import cc.rengu.igas.bsps.common.dao.impl.BspSequenceMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBaseInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBindInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsQrCodeInfoMapperImpl;
import cc.rengu.igas.bsps.common.entity.MchntBaseInfo;
import cc.rengu.igas.bsps.common.entity.MchntBindInfo;
import cc.rengu.igas.bsps.common.entity.QrCodeInfo;
import cc.rengu.igas.bsps.common.enums.QrCodeTypeEnum;
import cc.rengu.igas.bsps.common.enums.RespCodeEnum;
import cc.rengu.igas.bsps.core.realize.PublicDealService;
import cc.rengu.igas.bsps.core.realize.impl.PublicDealServiceImpl;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.request.MchntQrCodeBindOrUnBindRequest;
import cc.rengu.igas.bsps.facade.response.MchntQrCodeBindOrUnBindResponse;
import cc.rengu.jradp.asynnotify.AsynNotify;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.SysParamMapper;
import cc.rengu.oltp.service.common.dao.impl.SysParamMapperImpl;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.*;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhangxuran
 * @version 1.0
 * 二维码绑定及解绑交易操作
 */
public class MchntQrCodeBindOrUnBindService extends ManageService {
    /**
     * 分隔符 /
     */
    private static final String NETWORK_SEPARATOR = "/";

    @Override
    protected Object bizBeforeCust() throws Exception {
        MchntQrCodeBindOrUnBindRequest mchntQrCodeBindOrUnBindRequest = new MchntQrCodeBindOrUnBindRequest();
        ConvertUtil.convertOutput(mchntQrCodeBindOrUnBindRequest);
        return mchntQrCodeBindOrUnBindRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        MchntQrCodeBindOrUnBindRequest mchntQrCodeBindOrUnBindRequest = (MchntQrCodeBindOrUnBindRequest) request;
        MchntQrCodeBindOrUnBindResponse mchntQrCodeBindOrUnBindResponse = new MchntQrCodeBindOrUnBindResponse();
        BizResponse<MchntQrCodeBindOrUnBindResponse> bizResponse = new BizResponse<>();
        /*获取法人行号标识、用户标识、商户号、二维码URL、二维码编码、操作类型*/
        String instId = mchntQrCodeBindOrUnBindRequest.getHeader().getInstId();
        String userId = mchntQrCodeBindOrUnBindRequest.getUserId();
        String mchntNo = mchntQrCodeBindOrUnBindRequest.getMchntNo();
        String qrUrl = mchntQrCodeBindOrUnBindRequest.getQrUrl();
        String qrCode = mchntQrCodeBindOrUnBindRequest.getQrCode();
        String opType = mchntQrCodeBindOrUnBindRequest.getOpType();
        String userRole = mchntQrCodeBindOrUnBindRequest.getUserRole();
        String qrCodeName = mchntQrCodeBindOrUnBindRequest.getQrCodeName();

        rglog.info("法人行标识:" + instId + "用户标识:" + userId + "商户号:" + mchntNo + "二维码URL:" + qrUrl + "二维码编码:" + qrCode + "操作类型:" + opType);
        if ((StringUtil.isEmptyOrNull(instId) || StringUtil.isEmptyOrNull(userId) || StringUtil.isEmptyOrNull(mchntNo) || StringUtil.isEmptyOrNull(opType) ||
                (StringUtil.isEmptyOrNull(qrUrl) && StringUtil.isEmptyOrNull(qrCode))) || StringUtil.isEmptyOrNull(userRole)) {
            rglog.error("必填性校验失败！");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }
        qrUrl = qrUrl.replaceAll("pay/PYCodePay.do", "epay-h5/COPS/qr-code-payment");
        /*查询二维码信息，判断二维码是否允许相应操作*/
        SysParamMapper sysParamMapper = new SysParamMapperImpl();
        BspsQrCodeInfoMapper qrCodeMapper = new BspsQrCodeInfoMapperImpl();
        BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        QrCodeInfo qrCodeInfo;
        boolean obqrFlag = false;
        if ("00".equals(opType)) {
            rglog.info("绑码操作");
            BspsMchntBaseInfoMapper bspsMchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
            MchntBaseInfo mchntBaseInfo = bspsMchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, mchntNo);
            if ("00".equals(userRole)) {
                rglog.info("商户收银员绑定二维码");
                rglog.info("判断是否支持绑定C1码");
                SysParam c1QrcodeParam = sysParamMapper.selectSysParamByPrimaryKey(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.C1_CODE_KEY);
                if (null != c1QrcodeParam && BspsAppParamConstant.FLAG_Y.equals(c1QrcodeParam.getParamValue())) {
                    rglog.info("支持绑定C1码");
                    if (!StringUtil.isEmptyOrNull(qrUrl) && qrUrl.contains("&tt")) {
                        rglog.info("二维码为C1码：" + qrUrl);
                        qrUrl = qrUrl.substring(0, qrUrl.indexOf("&tt"));
                        rglog.info("二维码信息qrUrl：" + qrUrl);
                    }
                }
                rglog.info("查询二维码信息");
                qrCodeInfo = queryQrcoeInfo(instId, qrUrl, qrCode);
                if (null == qrCodeInfo) {
                    rglog.error("查询二维码失败");
                    throw new BizException(RespCodeEnum.INVALID_QRCODE_ERROR.getRespCode(), RespCodeEnum.INVALID_QRCODE_ERROR.getRespDesc());
                }
                rglog.info("获取用户信息");
                /*获取用户绑定商户信息*/
                MchntBindInfo mchntBindInfo = bspsMchntBindInfoMapper.selectBspsMchntBindInfoListByUserIdAndMchntNo(instId, userId, mchntNo);
                if (null != mchntBindInfo) {
                    qrCodeInfo.setChainMchntNo(mchntBindInfo.getChainMchntNo());
                    qrCodeInfo.setUserId(userId);
                } else {
                    rglog.error("用户绑定商户信息获取失败");
                    throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
                }
            } else if ("10".equals(userRole)) {
                rglog.info("拓展经理绑码");
                qrCodeInfo = queryQrcoeInfo(instId, qrUrl, qrCode);
                String qrcodeUserId = null;
                List<MchntBindInfo> mchntBindInfolist = bspsMchntBindInfoMapper.selectBspsMchntBindInfoByMchntNo(instId, mchntNo);
                if (!CollectionUtils.isEmpty(mchntBindInfolist)) {
                    mchntBindInfolist = mchntBindInfolist.stream().filter(item -> ("00".equals(item.getBindUserRole()) || "01".equals(item.getBindUserRole()))).collect(Collectors.toList());
                }
                if (!CollectionUtils.isEmpty(mchntBindInfolist)) {
                    rglog.info("存在法人用户或者店长用户，角色信息:" + mchntBindInfolist.get(0).getBindUserRole());
                    qrcodeUserId = mchntBindInfolist.get(0).getBindUserId();
                }
                if (null == qrCodeInfo) {
                    rglog.info("查询二维码信息为空，判断是否支持他行码绑定");
                    SysParam obQrodeParam = sysParamMapper.selectSysParamByPrimaryKey(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.OBQR_KEY);
                    if (null != obQrodeParam && BspsAppParamConstant.FLAG_Y.equals(obQrodeParam.getParamValue())) {
                        rglog.info("支持绑定他行码");
                        obqrFlag = true;
                        ManageOtherQrcode(instId, mchntNo, userId, qrUrl, mchntBaseInfo, qrcodeUserId);
                    } else {
                        rglog.error("不支持他行码，无效二维码信息");
                        throw new BizException(RespCodeEnum.INVALID_QRCODE_ERROR.getRespCode(), RespCodeEnum.INVALID_QRCODE_ERROR.getRespDesc());
                    }
                }
                //赋值二维码绑定用户id
                if (!StringUtil.isEmptyOrNull(qrcodeUserId) && !obqrFlag) {
                    rglog.info("二维码存在，赋值绑定用户ID:" + qrcodeUserId);
                    qrCodeInfo.setUserId(qrcodeUserId);
                }
            } else {
                throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
            }
            if (obqrFlag) {
                bizResponse.setRspSysId(AppParamConstant.SYS_ID);
                bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
                bizResponse.setResult(mchntQrCodeBindOrUnBindResponse);
                return bizResponse;
            }
            //判断二维码状态
            if (!"00".equals(qrCodeInfo.getQrStatus())) {
                rglog.error("二维码状态异常" + qrCodeInfo.getQrStatus());
                throw new BizException(RespCodeEnum.INVALID_QRCODE_ERROR.getRespCode(), RespCodeEnum.INVALID_QRCODE_ERROR.getRespDesc());
            }
            if (!"00".equals(qrCodeInfo.getBindStatus())) {
                rglog.error("二维码绑定状态异常" + qrCodeInfo.getBindStatus());
                throw new BizException(RespCodeEnum.QRCODE_EXIST_ERROR.getRespCode(), RespCodeEnum.QRCODE_EXIST_ERROR.getRespDesc());
            }
            if (!StringUtil.isEmptyOrNull(qrCodeInfo.getMchntNo()) && !mchntNo.equals(qrCodeInfo.getMchntNo())) {
                rglog.error("二维码属于商户:" + qrCodeInfo.getMchntNo());
                throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
            }
            qrCodeInfo.setMchntNo(mchntNo);
            qrCodeInfo.setLastOprId(userId);
            qrCodeInfo.setBindStatus("01");
            qrCodeInfo.setEffectiveTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            qrCodeInfo.setLastUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            qrCodeInfo.setQrCodeName(qrCodeName);
            int iReturnCode = qrCodeMapper.updateBspsQrCodeInfoById(qrCodeInfo);
            if (0 != iReturnCode) {
                rglog.error("绑定二维码失败!");
                throw new BizException(RespCodeEnum.UPDATE_QRCODE_INFO_ERROR.getRespCode(), RespCodeEnum.UPDATE_QRCODE_INFO_ERROR.getRespDesc());
            }

            rglog.info("二维码绑定成功,异步调用终端信息报备服务");
            xmlTreeUtil.setXmlTreeStringValue(BspsTreeNodeConstant.TERM_NO, qrCodeInfo.getQrNum());
            xmlTreeUtil.setXmlTreeStringValue(BspsTreeNodeConstant.MCHNT_NO, mchntNo);
            iReturnCode = asynnotify.transactionNotice(BspsServiceNameConstant.ASYN_TERM_INFO_REPORT_SERVICE, 1, AsynNotify.GAP_SAME, 0);
            if (0 != iReturnCode) {
                rglog.error("异步调用终端信息报备服务失败,iReturnCode:<{}>", iReturnCode);
            }
        } else if ("01".equals(opType)) {
            if (!"00".equals(userRole)) {
                rglog.error("非商户无权解绑二维码!");
                throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
            }
            qrCodeInfo = queryQrcoeInfo(instId, qrUrl, qrCode);
            /*解绑二维码操作*/
            /*判断是否拥有权限进行解绑*/
            PublicDealService publicDealService = new PublicDealServiceImpl();
            boolean opAuthFlag = publicDealService.checkUserOpAuth(instId, mchntNo, userId, qrCodeInfo.getUserId());
            if (!opAuthFlag) {
                rglog.error("用户无权解绑该二维码，用户标识:" + userId + "用户商户号：" + mchntNo + "二维码绑定收银员标识:" + qrCodeInfo.getUserId() + "二维码商户号:" + qrCodeInfo.getMchntNo());
                throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
            }
            /* 绑定状态修改为解绑状态 00 ,用户为最后修改人员 */
            qrCodeInfo.setUserId("");
            qrCodeInfo.setLogoUrlPath("");
            qrCodeInfo.setBindStatus("00");
            qrCodeInfo.setLastOprId(userId);
            qrCodeInfo.setLastUpdateTime(DateUtil.getCurrentDateTime(BspsAppParamConstant.yyyy_MM_dd_HHmmssSSS));
            qrCodeInfo.setQrCodeName(qrCodeName);
            int iReturnCode = qrCodeMapper.updateBspsQrCodeInfoById(qrCodeInfo);
            if (0 != iReturnCode) {
                rglog.error("解绑二维码失败!");
                throw new BizException(RespCodeEnum.UPDATE_QRCODE_INFO_ERROR.getRespCode(), RespCodeEnum.UPDATE_QRCODE_INFO_ERROR.getRespDesc());
            }
        }
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(mchntQrCodeBindOrUnBindResponse);
        return bizResponse;
    }

    /**
     * 他行码绑定
     * 创建空白二维码，将他行码和本行空白二维码映射关系保存
     *
     * @param instId  法人行
     * @param mchntNo 商户号
     * @param userId  用户标识
     * @param qrUrl   他行码URL信息
     */
    private void ManageOtherQrcode(String instId, String mchntNo, String userId, String qrUrl, MchntBaseInfo mchntBaseInfo, String qrcodeUserId) throws Exception {
        rglog.info("绑定他行码");
        /* 根据机构号获取二维码类型 */
        String qrCodeType;
        SysParamMapper sysParamMapper = new SysParamMapperImpl();
        SysParam instQrCodeTypeSysParam = sysParamMapper.selectSysParamByPrimaryKey(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.INST_QRCODE_TYPE);
        if (null != instQrCodeTypeSysParam) {
            qrCodeType = instQrCodeTypeSysParam.getParamValue();
        } else {
            qrCodeType = QrCodeTypeEnum.IGAS.getCodeType();
        }

        StringBuilder qrCode = new StringBuilder();
        if (QrCodeTypeEnum.CUPS.getCodeType().equals(qrCodeType)) {
            rglog.info("生成银标码");
            //银联二维码域名 https://qr.95516.com/
            qrCode.append(BspsAppParamConstant.CUPS_QRCODE_DOMAIN_NAME);
            /* 银联码，获取法人行在银联的机构号 */
            SysParam unionPayCode = sysParamMapper.selectSysParamByPrimaryKey(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.CUPS_INSR_ID);
            if (null == unionPayCode) {
                rglog.error("机构二维码类型为银联二维码，获取法人行在银联的机构号失败！instId:{}", instId);
                throw new BizException(RespCodeEnum.BIND_QRCODE_ERROR.getRespCode(), RespCodeEnum.BIND_QRCODE_ERROR.getRespDesc());
            }
            qrCode.append(unionPayCode.getParamValue()).append(NETWORK_SEPARATOR);
        } else if (QrCodeTypeEnum.IGAS.getCodeType().equals(qrCodeType)) {
            rglog.info("生成本行码");
            //银行二维码域名
            SysParam bankDomainName = sysParamMapper.selectSysParamByPrimaryKey(instId, BspsAppParamConstant.MCHNT_PARAM_TYPE, BspsAppParamConstant.MCHNT_QRCODE_DOMAIN_NAME);
            if (null == bankDomainName) {
                rglog.error("生成收款聚合码服务处理失败！获取收款聚合码银行域名参数失败， instId:{}。", instId);
                throw new BizException(RespCodeEnum.BIND_QRCODE_ERROR.getRespCode(), RespCodeEnum.BIND_QRCODE_ERROR.getRespDesc());
            }
            qrCode.append(bankDomainName.getParamValue());
        }
        //拼接静态码标识
        qrCode.append("inf=S");
        rglog.info("获取二维码序列号");
        BspSequenceMapper bspSequenceMapper = new BspSequenceMapperImpl();
        String seq = bspSequenceMapper.getNextQrCodeSeq(8);
        qrCode.append(seq);
        rglog.debug("qrCode：{}", qrCode.toString());

        QrCodeInfo qrCodeInfo = new QrCodeInfo();
        qrCodeInfo.setInstId(instId);
        qrCodeInfo.setId(RandomUtil.getUUID());
        qrCodeInfo.setQrCodeType(QrCodeTypeEnum.OBQR.getCodeType());
        qrCodeInfo.setQrUrl(qrUrl);
        qrCodeInfo.setRelationQrCode(qrCode.toString());
        qrCodeInfo.setQrCode(seq);
        //0-客户输入  1-固定金额
        qrCodeInfo.setSrcAmtType("0");
        //00-正常状态  01-停用状态
        qrCodeInfo.setQrStatus("00");
        qrCodeInfo.setMchntNo(mchntNo);
        //连锁商户号
        if (null != mchntBaseInfo) {
            qrCodeInfo.setChainMchntNo(mchntBaseInfo.getChainMchntNo());
        }
        qrCodeInfo.setRelationQrCode(qrCode.toString());
        //00-未绑定状态  01-绑定状态
        qrCodeInfo.setBindStatus("00");
        //二维码绑定用户
        if (!StringUtil.isEmptyOrNull(qrcodeUserId)) {
            qrCodeInfo.setUserId(qrcodeUserId);
        }
        qrCodeInfo.setEffectiveTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        qrCodeInfo.setOprId(userId);
        qrCodeInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        BspsQrCodeInfoMapper manageQrcodeMapper = new BspsQrCodeInfoMapperImpl();
        int insertReturnCode = manageQrcodeMapper.insertBspsQrCodeInfo(qrCodeInfo);
        if (0 != insertReturnCode) {
            rglog.error("绑定他行二维码失败！");
            throw new BizException(RespCodeEnum.BIND_QRCODE_ERROR.getRespCode(), RespCodeEnum.BIND_QRCODE_ERROR.getRespDesc());
        }
    }

    /**
     * 根据二维码url或者qrCode查询二维码信息
     *
     * @param instId 法人行号
     * @param qrUrl  二维码URL
     * @param qrCode 二维码编码
     *               return qrcodeInfo
     */
    private QrCodeInfo queryQrcoeInfo(String instId, String qrUrl, String qrCode) throws Exception {
        BspsQrCodeInfoMapper qrCodeInfoMapper = new BspsQrCodeInfoMapperImpl();
        QrCodeInfo queryQrcodeInfo;
        if (!StringUtil.isEmptyOrNull(qrUrl)) {
            rglog.info("根据qrUrl查询二维码信息：" + qrUrl);
            queryQrcodeInfo = qrCodeInfoMapper.selectBspsQrCodeInfoByPrimaryKey(instId, qrUrl);
        } else {
            rglog.info("根据qrCode查询二维码信息：" + qrCode);
            queryQrcodeInfo = qrCodeInfoMapper.selectBspsQrCodeInfoByQrCode(instId, qrCode);
        }
        return queryQrcodeInfo;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MchntQrCodeBindOrUnBindResponse mchntQrCodeBindOrUnBindResponse = (MchntQrCodeBindOrUnBindResponse) bizResponse.getResult();
        ConvertUtil.convertInput(mchntQrCodeBindOrUnBindResponse);
    }
}
